#include <iostream>
#include "ui_prototype.h"
#include <QtGui> 
#include "proto.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Model/ssm_conversions.h"
#include <QtCore>
//#include "ssm.h"
#include "gracesc.h"
#include <pthread.h>
#include <libgpsmm.h>
#include <math.h>
#include "WorkerThread.h"

// including <QtGui> saves us to include every class user, <QString>, <QFileDialog>,...

WorkerThread myThread;


//main entry point from the main
//this is where we do all the main initializing points
Proto::Proto(QMainWindow *parent)
{
	setupUi(this);		// this sets up GUI
	loaded=false;		//we do not have a plan/route file loaded, so initialize this no no	
	changed=false;		//same as above
	currentLeg=0;		//initialize the leg to 0, this is still in development
	myThread.setDialog((Proto*)this);
	running = false;

	// connect signals to slots, this is how QT allows widgets to communicate with each other
	connect( runModelButton, SIGNAL( clicked() ), this, SLOT( runModel() ) );		//connects the button to the function runModel()
	connect( changeWaypoint, SIGNAL( clicked() ), this, SLOT( changeWay()) );		//connects the change current waypoint function to but.	
	connect(startGraphButton,      SIGNAL( clicked() ), this, SLOT( startWorker())     );
	connect(actionOpen_Route_File, SIGNAL(triggered()), this, SLOT(openRoute()));		//connects the menu button open to the function openRoute
	connect(actionExit,	       SIGNAL(triggered()), this, SLOT(Exit()));		//connects the menu button exit to the function Exit
	connect(actionSave_Route_File, SIGNAL(triggered()), this, SLOT(saveRoute()));		//connects the menu button save to the function saveRoute
	connect(actionClose_Route_and_Plan_File, SIGNAL(triggered()),this,SLOT(close()));	//connects the menu button close to the function close
	connect(&myThread, SIGNAL(dashboardUpdated() ),this,SLOT(updateDashboard()));	//connects the threads signal to updatedash
	connect(actionClose_Route_and_Plan_File, SIGNAL(triggered()),this,SLOT(close()));	//connects the menu button close to the function close	
	
	odometer = 0;
	setupLCDs();

}

//turns LCDs black and sets ranges for color changing
void Proto::setupLCDs(){
	FILE *defaults;
	
	//initialize lcds to be black and readable
	speedLcd->setPalette( QPalette(QColor(0,0,0)));
	odometerLcd->setPalette( QPalette(QColor(0,0,0)));
	tempMotorLcd->setPalette( QPalette(QColor(0,0,0)));
	tempContLcd->setPalette( QPalette(QColor(0,0,0)));
	voltageLcd->setPalette( QPalette(QColor(0,0,0)));
	currentLcd->setPalette( QPalette(QColor(0,0,0)));

	if((defaults=fopen("dashboard.defaults","r"))==NULL)
	{			//could not open file, so use default values for boundry conditions
		DELTADISTANCE=	1;
		MAXMOTORTEMP=	180;
		MAXCONTTEMP=	180;
		MAXVOLTAGE=	15;
		MINVOLTAGE=	10;
		MAXCURRENT=	90;	
		MINCURRENT=	10;	

	}

	if(fscanf(defaults, "DELTADISTANCE %f\nMAXMOTORTEMP %f\nMAXCONTTEMP %f\nMAXVOLTAGE %f\nMINVOLTAGE %f\nMAXCURRENT %f\nMINCURRENT %f",
						//read from the file
		&DELTADISTANCE,
		&MAXMOTORTEMP,
		&MAXCONTTEMP,
		&MAXVOLTAGE,
		&MINVOLTAGE,
		&MAXCURRENT,	
		&MINCURRENT)!=7)
	{					//again, if we cannot read from the file, we should just use default values
		DELTADISTANCE=	1;
		MAXMOTORTEMP=	180;
		MAXCONTTEMP=	180;
		MAXVOLTAGE=	15;
		MINVOLTAGE=	10;
		MAXCURRENT=	90;	
		MINCURRENT=	10;
	}
}

//this function starts the model when the button is pressed
//it uses the paths of the currently loaded route/plan file
void Proto::runModel() 
{	
	
	char temp[4096];		//temp array for generating the system call to run the model

	if(!loaded)									//if there is no model loaded, do not do anything
	{
		QMessageBox::about(this, "ERROR","No route or plan loaded\n");
		return;	
	}

									//if the route or plan file has been changed, save it first
	if (!QMessageBox::question(this,
		tr("Save?"),
		tr("Do you wish to save?"),
		tr("&Yes"), 
		tr("&No"),
		QString::null, 0, 1 ))	

		saveRoute();	

	if(data_file->text().toLatin1().data()=="")					//we must specify a datafile for output. There are other errors
	{										//that the user could put in, but for now we are not checking this
		QMessageBox::about(this, "ERROR","You must first specify a data file for output\n");
		return;
	}							

	strcpy(temp,	"./Model/ssm ");		//this part makes the function call to system so that it has all the right command line arguments
	strcat(temp,	r_file);		//this is the route file
	strcat(temp,	" ");			//spacer
	strcat(temp,	p_file);		//plan file
	strcat(temp,	" ");			//spacer
	strcat(temp,	data_file->text().toLatin1().data());	//where to store the results
	
	//#ifdef DEBUG
		fprintf(stderr,"%s\n",temp);
	//#endif	
	system(temp);				//run the model

}

//closes the currently opened route and plan file
//mainly used if we just want to open a different route and/or plan file
void Proto::close()
{
	if(!loaded)		//if there is currently no opened route and plan file, do nothing
		return;
	int rows=tableWidget->rowCount();		//get the current number of legs=rows in the table

	//if(!QMessageBox::question(this,"Do you wish to save?","Save File?",QMessageBox::Yes,QMessageBox::No,QMessageBox::NoButton))
	if (!QMessageBox::question(this,
		tr("Save?"),
		tr("Do you wish to save?"),
		tr("&Yes"), 
		tr("&No"),
		QString::null, 0, 1 ))	

	
		saveRoute();				//if they want to save, call the function save

	for(int x=(rows-1);x>=0;x--)		//remove all of the information from the table
	{
		tableWidget ->removeRow(x);
		tableWidget2->removeRow(x);

	}
	loaded=false;
				//we no longer have a route file loaded, so set these to NULL and make the text display nothing
	route_text->setText("");
	plan_text ->setText("");

	//now, we update current waypoint info to not display anything

	legDistanceLcd->display(0);
	legNumber->display(1);
	speedLimitLcd->display(0);

	return;

}

//this function opens a route and a plan file together
//it displays all the information in the table
void Proto::openRoute()
{
	QString route_file;		//file dialog returns a Qstring, this is just temporary until we can convert it
	QString plan_file;
	int x;				//for for loops
	QTableWidgetItem *item;		//for adding items to the tables
	char string[20];		//to convert to strings from information route information

	if(loaded)			//makes sure there is not currently a route and a plan file open
	{				//if not just quit and let the person know 
		QMessageBox::about(this, "ERROR","ERROR:You must first close the other route and plan file\n");
		return;
	}

	route_file = QFileDialog::getOpenFileName(this,"Choose a route file to open",	QString::null, QString::null);	//get the file names
	plan_file = QFileDialog::getOpenFileName(this,"Choose a plan file to open",	QString::null, QString::null);

	Route rou;		//store the information

	if(read_route(route_file.toLatin1().data(), plan_file.toLatin1().data(), &rou)!=0)	//this reads in all of the information into the structure 
	{											//route
		QMessageBox::about(this, "ERROR Opening Files","ERROR:Cannot open route or plan file\n");
		return;
	}

	route=rou;		//this makes the pointer under proto point to this structure
	
	for(x=0;x<=rou.nleg;x++)	//giant loop that adds all the information to the table
	{				//adds to both tables
		tableWidget->insertRow(x);
		tableWidget2->insertRow(x);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].distance);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 0,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].latitude);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 1,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].longitude);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 2,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].altitude);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 3,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].speed_limit);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 4,item);	

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].stops);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 5,item);	

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].hills);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 6,item);	
		
		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].d_x);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 7,item);	

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].d_y);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 8,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].d_z);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 9,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].suntime);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget->setItem(x, 10,item);		

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].speed);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget2->setItem(x, 0,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].windspeed);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget2->setItem(x, 1,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].windheading);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget2->setItem(x, 2,item);

		item = new QTableWidgetItem();
		sprintf(string,"%f",rou.leg[x].shade);
    		item->setText(QApplication::translate("mainForm",string , 0, QApplication::UnicodeUTF8));
    		tableWidget2->setItem(x, 3,item);
	
	}
	
	route_text->setText(route_file.toLatin1().data());	//change the text above the tables to reflect the newly loaded file
	plan_text->setText(plan_file.toLatin1().data());	
	
	strcpy(version	, rou.version);				//update the route information to reflect the newly loaded file
	strcpy(comment	, rou.comment);				//these are private data members
	strcpy(units	, rou.units);	

	loaded=true;						//we now loaded a file, so switch this to true

	version_line->setText( QString(version));		//update the form
	comment_line->setText( QString(comment));
	units_line  ->setText( QString(units  ));

	strcpy(r_file,route_file.toLatin1().data());		//again, just updating the private members
	strcpy(p_file,plan_file.toLatin1().data());

	#ifdef DEBUG
		fprintf(stderr,"route file %s\nplan file %s\n",r_file,p_file);
	#endif

	//now we need to updsate the current waypoint information, we initialize it to 0, and the user can increase it
	legDistanceLcd->display(route.leg[0].distance);
	legNumber->display(1);
	speedLimitLcd->display(route.leg[0].speed_limit);

	return;
}

//this function saves the currently opened route and plan files
void Proto::saveRoute()
{
	fprintf(stderr,"Saving...\n");

	if(loaded==false)		//if no file is loaded, it is pointless to save a file
	{
		QMessageBox::about(this, "ERROR: No open files","You must first have a route and plan file open\n");
		return;
	}
		
	FILE *rfp;		//route file pointer
	FILE *pfp;		//plan file pointer
	int i=0;		//for loop counter
	int nlegs;		//number of rows

	float distance, latitude, longitude, altitude, speed_limit, stops, hills, dx, dy, dz, suntime;
	float speed, wspeed, whead, shade;

	QString route_file;
	QString plan_file;
	
	route_file = QFileDialog::getSaveFileName(this,"File name to save route file to...",	QString::null, QString::null);	//figure out where to save
	plan_file = QFileDialog::getSaveFileName(this, "File name to save plan file to...",	QString::null, QString::null);	//the files to
	
	if((rfp=fopen(route_file.toLatin1().data(),"w+"))==NULL)
	{
		QMessageBox::about(this, "ERROR","Could not save\n");
		return;

	}		//opens the files
	if((pfp=fopen(plan_file.toLatin1().data() ,"w+"))==NULL)
	{
		QMessageBox::about(this, "ERROR"," Could not save\n");
		return;
	}
	
	nlegs=tableWidget->rowCount();

	
	fprintf(rfp,"version %s\n", version_line->text().toLatin1().data());		//prints out the verion, comment, and units information
	fprintf(rfp,"comment %s\n", comment_line->text().toLatin1().data());		//this is taken from the line edit in the form
	fprintf(rfp,"units %s\n",   units_line  ->text().toLatin1().data());

	fprintf(rfp,"nleg %d\n", (nlegs-1));						//outputs the number of legs
	
	fprintf(rfp,"targetBatt 1.0\ntargetTime 61200\n");
	
	fprintf(pfp,"This plan file was automated by the sunseeker performance modeling program\n");

	for(i=0; i < nlegs; i++)			//the following set of loops converts the item at a spot to a float
	{

		if(sscanf(tableWidget->item(i,0)->text().toLatin1().data(),"%f",&distance)!=1)		//distance
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,1)->text().toLatin1().data(),"%f",&latitude)!=1)		//lat
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,2)->text().toLatin1().data(),"%f",&longitude)!=1)		//longitude
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,3)->text().toLatin1().data(),"%f",&altitude)!=1)		//altitude
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,4)->text().toLatin1().data(),"%f",&speed_limit)!=1)	//speed limit
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,5)->text().toLatin1().data(),"%f",&stops)!=1)		//stops
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,6)->text().toLatin1().data(),"%f",&hills)!=1)		//hills
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,7)->text().toLatin1().data(),"%f",&dx)!=1)		//dx
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,8)->text().toLatin1().data(),"%f",&dy)!=1)		//dy
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,9)->text().toLatin1().data(),"%f",&dz)!=1)		//dz
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget->item(i,10)->text().toLatin1().data(),"%f",&suntime)!=1)		//suntime
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
	
		fprintf(rfp,"%d %f %f %f %f %f %f %f %f %f %f %f\n",
			i, distance, latitude, longitude, altitude, speed_limit,
			stops, hills, dx, dy, dz, suntime);						//prints the information to the file
			
		if(sscanf(tableWidget2->item(i,0)->text().toLatin1().data(),"%f",&speed)!=1)		//speed
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget2->item(i,1)->text().toLatin1().data(),"%f",&wspeed)!=1)		//wind speed
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget2->item(i,2)->text().toLatin1().data(),"%f",&whead)!=1)		//wind heading
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		if(sscanf(tableWidget2->item(i,3)->text().toLatin1().data(),"%f",&shade)!=1)		//shade
		{
			QMessageBox::about(this, "ERROR"," Could not save\n");
			return;
		}
		
		fprintf(pfp,"%d %f %f %f %f\n",
			i, speed, wspeed, whead,shade);					//got to remeber to put an if statement in here
											//writes to the file

	}
		
	fclose(rfp);		//close both the route and the plan file
	fclose(pfp);

	route_text->setText(route_file.toLatin1().data());	//change the text above the tables to reflect the newly loaded file
	plan_text->setText(plan_file.toLatin1().data());

	changed=false;		//we have now saved all the information
}

void Proto::Exit()
{
	if(!loaded)			//if the information was changed, we should probably ask ans see if the user wants to save the information
		if(QMessageBox::question(this,"Do you wish to save?","Save File?",QMessageBox::Yes,QMessageBox::No,QMessageBox::NoButton))
			saveRoute();
	exit(0);

}



static int eat_comment(FILE *fp);  // eats commnts and white space
static int line;                   // line in file currently being read.

int read_route(const char *file, const char *plan_file, Route *route) 
{
	FILE *fp;
	FILE *plan;
	int  i;
	char ln[1024];		//for reading comments
	double i_i;	//for comparing the speed with the speed limit

	line=1;

	if((fp=fopen(file,"r")) == NULL) 
	{
		fprintf(stderr,"ERROR: can not open route file %s for input\n", file);
  		return(1);
	} 
	// Not checking the return value is ok, since on EOF the next call will be EOF too

	if((plan=fopen(plan_file,"r")) == NULL)
	{
		fprintf(stderr,"ERROR: can not open plan file\n"); 

	}

	/*
	For now, a comment is only present on the first line of the plan.dat file. This is a bad idea, because we assume there is a 
	comment on the first line. A future story will be to change this.
	*/
	if((fgets(ln,1024,plan)) == NULL)
	{
		fprintf(stderr,"ERROR: could not read from the plan file\n");
		return(1);
	}

	eat_comment(fp);
	if(fscanf(fp,"version %20s", route->version) != 1) 
	{
 		fprintf(stderr, "ERROR: in route file %s, line %d, expecting: version <string>\n", file, line);
  		return(1);
	}

	//

	eat_comment(fp);

	if(fscanf(fp,"comment %200[^#\n]", route->comment) != 1) 
	{
		fprintf(stderr, "ERROR: in route file %s, line %d, expecting: comment <string>\n", file, line);
		return(1);
	}

	eat_comment(fp);

	if(fscanf(fp,"units %20s", route->units) != 1) 
	{
		fprintf(stderr, "ERROR: in route file %s, line %d, expecting: units [metric | english]\n", file, line);
  		return(1);
	}

	if((strncmp(route->units,"metric", 6)) && (strncmp(route->units, "english", 7))) 
	{
  		fprintf(stderr, "ERROR: in route file %s, line %d, expecting: units [metric | english]\n", file, line);
  		return(1);
	}

	eat_comment(fp);
	
	if(fscanf(fp,"nleg %d", &route->nleg) != 1) 
	{
		fprintf(stderr, "ERROR: in route file %s, line %d, expecting: nleg <number>]\n", file, line);
  		return(1);
	}
	eat_comment(fp);

	if(fscanf(fp,"targetBatt %lf", &route->targetBatt) != 1) 
	{
  		fprintf(stderr, "ERROR: in route file %s, line %d, expecting: targetBatt <number>]\n", file, line);
  		return(1);
	}
	eat_comment(fp);

	if(fscanf(fp,"targetTime %lf", &route->targetTime) != 1) 
	{
  		fprintf(stderr, "ERROR: in route file %s, line %d, expecting: targetTime <number>]\n", file, line);
  		return(1);
	}

	if((route->leg = (Leg *)malloc((route->nleg+1)*sizeof(Leg))) == NULL) 
	{
  		fprintf(stderr, "ERROR: in route file %s, Can not malloc space for %d + 1 legs\n", file, route->nleg);
  		return(1);
	}
	//
	// Read the legs

	for(i=0; i<=route->nleg; i++)  
	{
  		//  # leg distance latitude longitude altitude speed_limit stops hills shade d_x d_y d_z
  		eat_comment(fp);
  
		if(fscanf(fp,"%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
       			&route->leg[i].i,
       			&route->leg[i].distance,
       			&route->leg[i].latitude,
       			&route->leg[i].longitude,
       			&route->leg[i].altitude,
       			&route->leg[i].speed_limit,
       			&route->leg[i].stops,
       			&route->leg[i].hills,
       			&route->leg[i].d_x, 
    			&route->leg[i].d_y, 
			&route->leg[i].d_z,
			&route->leg[i].suntime) != 12) 
			{
				fprintf(stderr, "ERROR: in route file %s, line %d, can not read leg %d\n", file, line, i);
				return(1);
			}
		
		if(fscanf(plan,"%lf %lf %lf %lf %lf\n",
			&i_i,
			&route->leg[i].speed,
			&route->leg[i].windspeed,
			&route->leg[i].windheading,
			&route->leg[i].shade) != 5)
		{
			fprintf(stderr,"ERROR: in plan file on leg %d\n",i);
			return(1);
		}
	
	
		printf("reading distance/speed = %f/%f\n", route->leg[i].distance, route->leg[i].speed_limit);
 		if(route->leg[i].i != i) 
		{
			fprintf(stderr, "ERROR: in route file %s, line %d, expecting leg %d found %d\n", file, line, i, route->leg[i].i);
    			return(1);
  		}
		if(route->leg[i].i != i_i) 
		{
			fprintf(stderr, "ERROR: in plan file on leg %d\n",i);
    			return(1);
  		}
	}
	//
	// Check that there is nothing else at the end of the file
	if(eat_comment(fp)!=EOF) 
	{
		fprintf(stderr, "ERROR: in route file %s, line %d, extra lines at end of file\n", file, line);
		return(1);
	}
	return 0;
}
//
//
// eat_comment() eats white space and commnets, incrementiong
// the line counter as it goes. If one of the fscanfs above
// eats a '\n' between parameters, the line count will be off.
// Perhaps the "line" count is not such a good idea here after all
// That can be fixed if above '\n' is not accepted as a delimiter
// between parameters. hummm....
static int eat_comment(FILE *fp) 
{
	int c;
	// Loop eatting a sequence of optiional white space and comments until
	// either an EOF or a non-comment appears.
	while(1) 
	{
  		// Eat white space, including '\r' for windows...
  		while((c=fgetc(fp)) != EOF) 
		{
    			if((c==' ') || (c=='\t') || (c=='\r')) 
			{
			      continue;
			}
			if(c=='\n') 
			{
				line++;
			 	continue;
			}
			break;
		}
		if(c==EOF)
		{
			return EOF;
		}
		// It was not a comment, so push the byte back and return.
		if(c!='#')
		{
			ungetc(c,fp);
			return 0;
		}
		// Eat the comment, 'till the end of the line.
		while((c=fgetc(fp)) != EOF) 
		{
			if(c=='\n') 
			{
				line++;
				break;
			}
		}
		if(c==EOF) 
		{
    			return EOF;
		}
	}
	// You should never get here.
	return -2;
}

//given two data points, determines the distance
//thanks to 'The Math Forum' for the formula
double Proto::distance(double lat1, double long1, double lat2, double long2)
{
	double dlat, dlong,a,c;
	double convert=M_PI/180;
	double R=6371;			//assumes kilometers		

	dlat= lat1-lat2;
	dlong=long1-long2;

	//We first need to convert it to radians from degree
	dlat =dlat *convert;
	dlong=dlong*convert;

	//a=Math.Pow(Math.Sin(dlat/2),2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Pow(Math.Sin(dlong/2),2);
	//c=2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1-a));

	a=pow(sin(dlat/2),2) + cos(lat1) * cos(lat2) * pow(sin(dlong/2),2);
	c=2 * atan2(sqrt(a), sqrt(1-a));
	
	return (R*c);
}


//true is returned if the value is updated
//determines if the current point you are at is within DELTADISTANCE, read in from the file dashboard.defaults
//this function will be used by the thread that gets the gps units, and it will call this
//in order for this to work, the user is going to have to update where you are when turning on the laptop
bool Proto::check(double lat1, double long1)
{
	if(currentLeg==nlegs)		//we are at the end of the route so do nothing
		return false;

	if(distance(lat1,long1,route.leg[currentLeg+1].latitude,route.leg[currentLeg+1].longitude)<=DELTADISTANCE)
	{
		//distance(lat1,long1,route->leg[currentLeg+1).latitude,route->leg[currentLeg+1].longitude)==distance change
								//this is where we adjust the distance to match the GPS unit

	#ifdef DEBUG
		fprintf(stderr,"Adjusted distance to %d\n",distance(lat1,long1,&route.leg[currentLeg+1].latitude,&route.leg[currentLeg+1].longitude));
	#endif

		return true;	//we did adjust the distance
	}
	return false;		//we did not adjust the distance
}

/*This function updates the dashboard on the main display*/
void Proto::updateDashboard()
{
	speedLcd->display(speed);
	odometerLcd->display(odometer);
	tempMotorLcd->display(tempMotor);
	tempContLcd->display(tempCont);
	voltageLcd->display(voltage);
	currentLcd->display(current);
	
	//if any of the data is out of range, turn red, else turn black
	if(tempMotor>MAXMOTORTEMP)
		tempMotorLcd->setPalette( QPalette(QColor(255,0,0)));
	else
		tempMotorLcd->setPalette( QColor(0,0,0));
	
	if(tempCont>MAXCONTTEMP)
		tempContLcd->setPalette( QPalette(QColor(255,0,0)));
	else
		tempContLcd->setPalette( QColor(0,0,0));
	
	if(voltage<MINVOLTAGE || voltage>MAXVOLTAGE)
		voltageLcd->setPalette( QPalette(QColor(255,0,0)));
	else
		voltageLcd->setPalette( QColor(0,0,0));

	if(current>MAXCURRENT || current<MINCURRENT)
		currentLcd->setPalette( QPalette(QColor(255,0,0)));
	else
		currentLcd->setPalette( QColor(0,0,0));
	
	//if there is currently a route and plan file loaded, make sure you are not going faster than
	//the current speed limit, if you are, turn red
	//if you are going faster than the current plan file speed, turn blue
	if(loaded){		
		if(speed>route.leg[currentLeg].speed_limit)
			speedLcd->setPalette( QPalette(QColor(255,0,0)));
		else if(speed>route.leg[currentLeg].speed)
			speedLcd->setPalette( QPalette(QColor(0,0,255)));
		else
			speedLcd->setPalette( QColor(0,0,0));
	}
	

}

//it will either start or stop the grpahing/ car stuff
void Proto::startWorker()
{
	if(!running){
		myThread.start();
		running = true;
	}
	else{
		myThread.stop();
		running = false;
	}
}

//this function changes the current waypoint and updates the information
//it is used by both the button on the gui and the thread that recieves gps signals
void Proto::changeWay()
{
	if(!loaded)									//if there is no model loaded, do not do anything
	{
		QMessageBox::about(this, "ERROR","No route or plan loaded\n");
		return;	
	}

	if(currentLeg>=route.nleg)
	{
		QMessageBox::about(this, "ERROR","Already at the last leg\n");
		return;
	}

	currentLeg++;	

	legDistanceLcd->display(route.leg[currentLeg].distance);
	legNumber->display(currentLeg+1);
	speedLimitLcd->display(route.leg[currentLeg].speed_limit);	

	return;
}

//this is the entry point for the thread that queries the gps
//it is responsible for finding the current position and increasing the waypoint if needed.
//for now, until we figure out gps/linux stuff, it is going to just quit
/*void* gpsThread(void* param)
{
	float latitude=42.0, longitude=-86.0;
	Proto *dialog=(Proto*)	param;

	dialog->legDistanceLcd->setPalette( QColor(0,0,0));		//make the color of the displays black so you can easily see 
	dialog->legNumber->setPalette( QColor(0,0,0));
	dialog->speedLimitLcd->setPalette( QColor(0,0,0));

	while(1)
	{
		if(!dialog->loaded)		//if there is currently no route/plan file loaded, there is no need to get gps coordinates
		{			//so just sleep for a second (should it be longer???) and check again after that
			sleep(1);	
			continue;
		}

		//this is the problem right here, we cannot read the gps device
		//but once we figure it out, it will go right here
				
		if(dialog->check(latitude,longitude))	//if true, it means that we have arrived at the next waypoint, so increase
		{
			dialog->changeWay();		//increase the current waypoint			
		}
		
		sleep(1);
	}
	
	pthread_exit(NULL);
}
*/


